from fastapi import APIRouter, Request
from fastapi.responses import PlainTextResponse, RedirectResponse
import pandas as pd
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

from models.models import Hotel, UserOrder, UserFavorite
from models.room_type import RoomType
from datetime import datetime, timedelta
import uuid
from typing import Optional
from urllib.parse import urlencode
from tools.comm import get_ali_object
from celery_app import celery_app
from tasks.order_tasks import cancel_unpaid_order
from tools.myredis import r

orders_router = APIRouter()


async def _mark_order_paid(order_no: str, transaction_no: Optional[str] = None):
    """
    更新订单为已支付状态，设置支付时间和交易号
    同时取消对应的 Celery 超时任务
    """
    if not order_no:
        return None

    order = await UserOrder.get_or_none(order_no=order_no)
    if not order:
        return None

    # 取消 Celery 超时任务（如果存在）
    try:
        task_key = f"order_task:{order_no}"
        task_id = r.get_str(task_key)
        if task_id:
            # 撤销任务
            celery_app.control.revoke(task_id, terminate=True)
            # 删除Redis中的任务ID
            r.delete(task_key)
            print(f"已取消订单 {order_no} 的超时任务，任务ID: {task_id}")
    except Exception as e:
        print(f"取消订单超时任务失败: {str(e)}")
        # 即使取消任务失败，也不影响订单状态更新

    # 若已为支付状态则不重复写入
    if order.status != 1:
        order.status = 1
        order.pay_time = datetime.now()
        if transaction_no and hasattr(order, "transaction_no"):
            order.transaction_no = transaction_no
        await order.save()
    elif transaction_no and hasattr(order, "transaction_no") and not order.transaction_no:
        # 补写交易号
        order.transaction_no = transaction_no
        await order.save(update_fields=["transaction_no"])

    return order


async def build_rating_matrix_from_db():
    """
    从数据库构建用户-酒店评分矩阵
    使用用户订单数据作为评分依据
    """
    # 获取所有酒店订单数据
    hotel_orders = await UserOrder.filter(product_type="hotel").all()
    
    # 如果没有订单数据，返回空结果
    if not hotel_orders:
        return None, None, None, None
    
    # 构建数据列表
    user_item_data = []
    for order in hotel_orders:
        # 简化处理：使用订单金额作为评分依据（需要根据实际业务逻辑调整）
        # 这里假设订单金额越高，用户满意度越高，转换为1-5分的评分
        rating = min(5.0, max(1.0, order.amount / 100))  # 简单映射，需要根据实际业务调整
        user_item_data.append([
            order.user_id, 
            order.product_id, 
            order.create_time.strftime("%Y-%m-%d"), 
            rating
        ])
    
    # 创建DataFrame
    df = pd.DataFrame(user_item_data, columns=["user_id", "hotel_id", "time", "rating"])
    users = df["user_id"].unique()
    hotels = df["hotel_id"].unique()
    
    # 创建评分矩阵
    rating_matrix = np.zeros((len(users), len(hotels)))
    for user_idx, user in enumerate(users):
        for hotel_idx, hotel in enumerate(hotels):
            rating = df[(df["user_id"] == user) & (df["hotel_id"] == hotel)]["rating"].values
            rating_matrix[user_idx, hotel_idx] = rating[0] if len(rating) > 0 else 0
    
    return df, users, hotels, rating_matrix


def calculate_user_similarity(rating_matrix):
    """
    计算用户相似度矩阵
    """
    user_similarity = cosine_similarity(rating_matrix)
    return user_similarity


def get_similar_users(user_id, users, user_similarity, k=2):
    """
    获取与目标用户最相似的K个用户
    """
    if user_id not in users:
        return []
    
    user_idx = np.where(users == user_id)[0][0]
    similarity_scores = user_similarity[user_idx]
    
    # 获取最相似的K个用户（排除自己）
    similar_user_indices = np.argsort(similarity_scores)[::-1][1:k+1]
    similar_users = [(users[idx], similarity_scores[idx]) for idx in similar_user_indices]
    
    return similar_users


def recommend_hotels_for_user(user_id, users, hotels, rating_matrix, user_similarity, top_n=3):
    """
    为用户推荐酒店
    """
    # 检查用户是否存在
    if user_id not in users:
        return []
    
    # 获取目标用户索引
    target_user_idx = np.where(users == user_id)[0][0]
    
    # 获取目标用户评分
    target_user_ratings = rating_matrix[target_user_idx]
    
    # 找出未评分的酒店
    unrated_hotel_indices = np.where(target_user_ratings == 0)[0]
    unrated_hotels = hotels[unrated_hotel_indices]
    
    if not unrated_hotels.size:
        return []  # 用户已评分所有酒店，无推荐
    
    # 获取相似用户
    similar_users = get_similar_users(user_id, users, user_similarity, k=2)
    if not similar_users:
        return []  # 无相似用户，无法推荐
    
    # 收集相似用户对未评分酒店的评分，按相似度加权
    hotel_scores = {}
    for sim_user_id, sim_score in similar_users:
        sim_user_idx = np.where(users == sim_user_id)[0][0]
        sim_user_ratings = rating_matrix[sim_user_idx]
        
        for hotel in unrated_hotels:
            hotel_global_idx = np.where(hotels == hotel)[0][0]
            hotel_rating = sim_user_ratings[hotel_global_idx]
            
            if hotel_rating > 0:  # 相似用户对该酒店有评分
                weighted_score = sim_score * hotel_rating
                if hotel not in hotel_scores or weighted_score > hotel_scores[hotel]:
                    hotel_scores[hotel] = weighted_score
    
    # 按加权得分排序，取Top-N
    sorted_hotels = sorted(hotel_scores.items(), key=lambda x: x[1], reverse=True)[:top_n]
    return sorted_hotels


@orders_router.get("/hotel")
async def get_hotel():
    """
    获取所有酒店信息

    """
    try:
        # 使用 prefetch_related 预加载关联的图片数据
        hotels = await Hotel.all().prefetch_related("images")
        hotels_list = []
        
        for hotel in hotels:
            images = []
            # 访问预加载的关联对象
            try:
                hotel_images = await hotel.images.all()
                for image in hotel_images:
                    images.append(
                        {
                            "id": image.id,
                            "image_url": image.image_url,
                            "is_main": image.is_main,
                            "sort": image.sort,
                            "create_time": image.create_time.isoformat() if image.create_time else None,
                            "update_time": image.update_time.isoformat() if image.update_time else None,
                        }
                    )
            except Exception as img_err:
                # 如果获取图片失败，记录错误但继续处理
                print(f"获取酒店 {hotel.id} 的图片失败: {img_err}")
                images = []

            hotels_list.append(
                {
                    "id": hotel.id,
                    "merchant_id": hotel.merchant_id,
                    "hotel_name": hotel.hotel_name,
                    "city": hotel.city,
                    "address": hotel.address,
                    "price": float(hotel.price) if hotel.price else 0.0,
                    "stock": int(hotel.stock) if hotel.stock else 0,
                    "facilities": hotel.facilities if hotel.facilities else [],
                    "status": int(hotel.status) if hotel.status is not None else 0,
                    "create_time": hotel.create_time.isoformat() if hotel.create_time else None,
                    "update_time": hotel.update_time.isoformat() if hotel.update_time else None,
                    "images": images,
                }
            )
        return {"code": 200, "message": "ok", "data": hotels_list}
    except Exception as e:
        import traceback
        error_msg = f"获取酒店列表失败: {str(e)}"
        print(f"错误详情: {error_msg}")
        print(traceback.format_exc())
        return {"code": 500, "message": error_msg, "data": []}


@orders_router.get("/hotel/recommend")
async def recommend_hotels(user_id: str, top_n: int = 3):
    """
    基于协同过滤算法为用户推荐酒店
    
    Args:
        user_id: 用户ID（字符串类型）
        top_n: 推荐酒店数量，默认为3
        
    Returns:
        推荐的酒店列表
    """
    try:
        # 从数据库构建评分矩阵
        df, users, hotels, rating_matrix = await build_rating_matrix_from_db()
        
        # 检查是否有足够的数据
        if df is None or len(users) == 0 or len(hotels) == 0:
            return {
                "code": 200, 
                "message": "ok", 
                "data": []
            }
        
        # 确保user_id类型一致（转换为字符串）
        user_id = str(user_id)
        
        # 计算用户相似度
        user_similarity = calculate_user_similarity(rating_matrix)
        
        # 生成推荐
        recommended_hotels = recommend_hotels_for_user(
            user_id, users, hotels, rating_matrix, user_similarity, top_n
        )
        
        # 获取推荐酒店的详细信息
        hotel_details = []
        for hotel_id, score in recommended_hotels:
            # 从数据库获取真实的酒店信息
            hotel = await Hotel.get_or_none(id=hotel_id)
            if hotel:
                # 获取酒店图片
                images = []
                hotel_images = await hotel.images.all()
                for image in hotel_images:
                    images.append({
                        "id": image.id,
                        "image_url": image.image_url,
                        "is_main": image.is_main,
                    })
                
                hotel_details.append({
                    "id": hotel.id,
                    "hotel_name": hotel.hotel_name,
                    "city": hotel.city,
                    "address": hotel.address,
                    "price": hotel.price,
                    "score": round(score, 2),
                    "images": images
                })
            
        return {
            "code": 200, 
            "message": "ok", 
            "data": hotel_details
        }
    except Exception as e:
        return {
            "code": 500, 
            "message": f"推荐失败: {str(e)}", 
            "data": []
        }


@orders_router.post("/hotel/preview")
async def preview_hotel_order(payload: dict):
    """
    订单确认页-价格试算
    入参:
      - hotel_id: 酒店ID
      - room_type_id: 房型ID
      - check_in_date: 入住日期 YYYY-MM-DD
      - check_out_date: 退房日期 YYYY-MM-DD
      - rooms: 间数，默认1
    """
    try:
        hotel_id = payload.get("hotel_id")
        room_type_id = payload.get("room_type_id")
        check_in_str = payload.get("check_in_date")
        check_out_str = payload.get("check_out_date")
        rooms = int(payload.get("rooms", 1))

        if not all([hotel_id, room_type_id, check_in_str, check_out_str]):
            return {"code": 400, "message": "缺少必要参数", "data": {}}

        check_in_date = datetime.strptime(check_in_str, "%Y-%m-%d").date()
        check_out_date = datetime.strptime(check_out_str, "%Y-%m-%d").date()
        nights = (check_out_date - check_in_date).days
        if nights <= 0:
            return {"code": 400, "message": "离店日期需晚于入住日期", "data": {}}

        hotel = await Hotel.get_or_none(id=hotel_id)
        room_type = await RoomType.get_or_none(id=room_type_id)
        if not hotel or not room_type:
            return {"code": 404, "message": "酒店或房型不存在", "data": {}}

        price_per_night = float(room_type.price or 0)
        original_price = float(room_type.original_price or price_per_night)
        base_amount = price_per_night * nights * rooms

        # 简单优惠：若房型有discount则直接减；否则若原价大于现价则算作优惠
        room_discount = float(room_type.discount or 0)
        crossed_discount = max(0.0, (original_price - price_per_night) * nights * rooms)
        promo_discount = max(room_discount * nights * rooms, crossed_discount)

        # 示例活动优惠：下单立减 75（如不符合可为0）
        activity_discount = 75.0 if base_amount >= 80 else 0.0

        total_discount = round(promo_discount + activity_discount, 2)
        payable = max(0.0, round(base_amount - total_discount, 2))

        # 主图
        images = []
        try:
            hotel_images = await hotel.images.all()
            for image in hotel_images:
                if image.is_main:
                    images.append({"id": image.id, "image_url": image.image_url, "is_main": True})
        except Exception:
            images = []

        return {
            "code": 200,
            "message": "ok",
            "data": {
                "hotel": {
                    "id": hotel.id,
                    "hotel_name": hotel.hotel_name,
                    "city": hotel.city,
                    "address": hotel.address,
                    "images": images
                },
                "room_type": {
                    "id": room_type.id,
                    "name": room_type.name,
                    "price": price_per_night
                },
                "stay": {
                    "check_in_date": check_in_date.isoformat(),
                    "check_out_date": check_out_date.isoformat(),
                    "nights": nights,
                    "rooms": rooms
                },
                "amounts": {
                    "base_amount": round(base_amount, 2),
                    "discount": total_discount,
                    "payable": payable,
                    "activity_discount": activity_discount
                }
            }
        }
    except Exception as e:
        return {"code": 500, "message": f"试算失败: {str(e)}", "data": {}}


@orders_router.post("/hotel/create")
async def create_hotel_order(payload: dict):
    """
    创建酒店订单（提交订单）
    需要前端已做过preview校验；此处仅做基础验证后落库
    """
    try:
        user_id = payload.get("user_id")
        hotel_id = payload.get("hotel_id")
        room_type_id = payload.get("room_type_id")
        check_in_str = payload.get("check_in_date")
        check_out_str = payload.get("check_out_date")
        rooms = int(payload.get("rooms", 1))
        amount = float(payload.get("amount", 0))

        if not all([user_id, hotel_id, room_type_id, check_in_str, check_out_str]):
            return {"code": 400, "message": "缺少必要参数", "data": {}}

        check_in_date = datetime.strptime(check_in_str, "%Y-%m-%d").date()
        check_out_date = datetime.strptime(check_out_str, "%Y-%m-%d").date()
        if (check_out_date - check_in_date).days <= 0:
            return {"code": 400, "message": "离店日期需晚于入住日期", "data": {}}

        # 简化：不扣减库存，仅创建订单
        order_no = f"ORD{datetime.now().strftime('%Y%m%d')}{uuid.uuid4().hex[:8].upper()}"
        order = await UserOrder.create(
            order_no=order_no,
            user_id=user_id,
            merchant_id=None,
            product_type="hotel",
            product_id=hotel_id,
            check_in_date=check_in_date,
            check_out_date=check_out_date,
            amount=amount,
            status=0
        )

        # 启动 Celery 定时任务：15分钟后自动取消未支付订单
        try:
            # 使用 apply_async 并设置 countdown（秒）来延迟执行
            task = cancel_unpaid_order.apply_async(
                args=[order_no],
                countdown=15 * 60  # 15分钟后执行（单位：秒）
            )
            # 将任务ID存储到Redis，以便后续取消任务
            task_key = f"order_task:{order_no}"
            r.set_str(task_key, task.id)
            # 设置过期时间为20分钟（比任务执行时间稍长）
            r.expire(task_key, 20 * 60)
            print(f"已为订单 {order_no} 启动15分钟倒计时任务，任务ID: {task.id}")
        except Exception as e:
            print(f"启动订单超时任务失败: {str(e)}")
            # 即使任务启动失败，也不影响订单创建

        return {
            "code": 200,
            "message": "ok",
            "data": {
                "order_id": order.id,
                "order_no": order_no,
                "status": order.status
            }
        }
    except Exception as e:
        return {"code": 500, "message": f"下单失败: {str(e)}", "data": {}}


@orders_router.get("/hotel/payment-info")
async def get_hotel_payment_info(order_no: str):
    """
    获取酒店订单支付页面所需信息
    """
    try:
        if not order_no:
            return {"code": 400, "message": "缺少订单号", "data": {}}

        order = await UserOrder.get_or_none(order_no=order_no)
        if not order:
            return {"code": 404, "message": "订单不存在", "data": {}}

        if order.product_type != "hotel":
            return {"code": 400, "message": "当前仅支持酒店订单", "data": {}}

        hotel = await Hotel.get_or_none(id=order.product_id)
        if not hotel:
            return {"code": 404, "message": "关联酒店不存在", "data": {}}

        images = []
        try:
            hotel_images = await hotel.images.all()
            for image in hotel_images:
                if image.is_main:
                    images.append(
                        {
                            "id": image.id,
                            "image_url": image.image_url,
                            "is_main": image.is_main,
                        }
                    )
        except Exception:
            images = []

        check_in_date = order.check_in_date.isoformat() if order.check_in_date else None
        check_out_date = order.check_out_date.isoformat() if order.check_out_date else None
        nights = 0
        if order.check_in_date and order.check_out_date:
            nights = max((order.check_out_date - order.check_in_date).days, 0)

        create_time = order.create_time or datetime.now()
        payment_deadline = (create_time + timedelta(minutes=15)).isoformat()

        data = {
            "order_no": order.order_no,
            "hotel": {
                "id": hotel.id,
                "hotel_name": hotel.hotel_name,
                "city": hotel.city,
                "address": hotel.address,
                "images": images,
            },
            "room_type": {
                "id": order.product_id,
                "name": getattr(hotel, "room_type", "酒店房型"),
                "price": float(hotel.price or 0.0),
            },
            "stay": {
                "check_in_date": check_in_date,
                "check_out_date": check_out_date,
                "nights": nights,
                "rooms": 1,
            },
            "amounts": {
                "base_amount": float(order.amount or 0.0),
                "discount": 0.0,
                "payable": float(order.amount or 0.0),
                "activity_discount": 0.0,
            },
            "payment_deadline": payment_deadline,
            "created_at": create_time.isoformat(),
        }

        return {"code": 200, "message": "ok", "data": data}
    except Exception as e:
        return {"code": 500, "message": f"获取订单信息失败: {str(e)}", "data": {}}


@orders_router.post("/create")
async def create_order(payload: dict):
    """
    通用创建订单接口
    支持创建各种类型的订单（flight/hotel/ticket）
    
    请求参数:
    - user_id: 用户ID (必需)
    - product_type: 产品类型 (必需) - flight/hotel/ticket
    - product_id: 产品ID (必需)
    - check_in_date: 入住日期 (YYYY-MM-DD) (必需)
    - check_out_date: 退房日期 (YYYY-MM-DD) (必需)
    - amount: 订单金额 (必需)
    - merchant_id: 商家ID (可选)
    """
    try:
        # 获取必需参数
        user_id = payload.get("user_id")
        product_type = payload.get("product_type")
        product_id = payload.get("product_id")
        check_in_str = payload.get("check_in_date")
        check_out_str = payload.get("check_out_date")
        amount = float(payload.get("amount", 0))
        
        # 可选参数
        merchant_id = payload.get("merchant_id")

        # 验证必需参数
        if not all([user_id, product_type, product_id, check_in_str, check_out_str]):
            return {"code": 400, "message": "缺少必要参数", "data": {}}

        # 验证产品类型
        valid_product_types = ["flight", "hotel", "ticket"]
        if product_type not in valid_product_types:
            return {"code": 400, "message": f"无效的产品类型，必须是以下之一: {valid_product_types}", "data": {}}

        # 解析日期
        check_in_date = datetime.strptime(check_in_str, "%Y-%m-%d").date()
        check_out_date = datetime.strptime(check_out_str, "%Y-%m-%d").date()
        
        # 验证日期逻辑
        if (check_out_date - check_in_date).days <= 0:
            return {"code": 400, "message": "退房日期需晚于入住日期", "data": {}}

        # 生成订单号
        order_no = f"ORD{datetime.now().strftime('%Y%m%d')}{uuid.uuid4().hex[:8].upper()}"
        
        # 创建订单
        order = await UserOrder.create(
            order_no=order_no,
            user_id=user_id,
            merchant_id=merchant_id,
            product_type=product_type,
            product_id=product_id,
            check_in_date=check_in_date,
            check_out_date=check_out_date,
            amount=amount,
            status=0  # 默认待支付状态
        )

        # 启动 Celery 定时任务：15分钟后自动取消未支付订单
        try:
            # 使用 apply_async 并设置 countdown（秒）来延迟执行
            task = cancel_unpaid_order.apply_async(
                args=[order_no],
                countdown=15 * 60  # 15分钟后执行（单位：秒）
            )
            # 将任务ID存储到Redis，以便后续取消任务
            task_key = f"order_task:{order_no}"
            r.set_str(task_key, task.id)
            # 设置过期时间为20分钟（比任务执行时间稍长）
            r.expire(task_key, 20 * 60)
            print(f"已为订单 {order_no} 启动15分钟倒计时任务，任务ID: {task.id}")
        except Exception as e:
            print(f"启动订单超时任务失败: {str(e)}")
            # 即使任务启动失败，也不影响订单创建

        return {
            "code": 200,
            "message": "订单创建成功",
            "data": {
                "order_id": order.id,
                "order_no": order_no,
                "status": order.status
            }
        }
    except Exception as e:
        return {"code": 500, "message": f"创建订单失败: {str(e)}", "data": {}}


@orders_router.post("/hotel/pay")
async def pay_hotel_order(payload: dict):
    """
    酒店订单支付接口
    """
    try:
        # 获取支付参数
        order_no = payload.get("order_no")
        amount = payload.get("amount")
        subject = payload.get("subject", "酒店订单支付")
        
        if not all([order_no, amount]):
            return {"code": 400, "message": "缺少必要参数", "data": {}}
        
        # 初始化支付宝对象
        alipay = get_ali_object()
        
        # 生成支付URL
        query_params = alipay.wap_pay(
            subject=subject,
            out_trade_no=str(order_no),
            total_amount=float(amount)
        )
        
        # 构建完整的支付URL
        gateway = alipay._AliPay__gateway
        pay_url = f"{gateway}?{query_params}"
        
        return {
            "code": 200,
            "message": "ok",
            "data": {
                "pay_url": pay_url
            }
        }
    except Exception as e:
        return {"code": 500, "message": f"生成支付链接失败: {str(e)}", "data": {}}


@orders_router.post("/pay")
async def pay_order(payload: dict):
    """
    通用订单支付接口
    """
    try:
        # 获取支付参数
        order_no = payload.get("order_no")
        amount = payload.get("amount")
        subject = payload.get("subject", "订单支付")
        
        if not all([order_no, amount]):
            return {"code": 400, "message": "缺少必要参数", "data": {}}
        
        # 初始化支付宝对象
        alipay = get_ali_object()
        
        # 生成支付URL
        query_params = alipay.wap_pay(
            subject=subject,
            out_trade_no=str(order_no),
            total_amount=float(amount)
        )
        
        # 构建完整的支付URL
        gateway = alipay._AliPay__gateway
        pay_url = f"{gateway}?{query_params}"
        
        return {
            "code": 200,
            "message": "ok",
            "data": {
                "pay_url": pay_url
            }
        }
    except Exception as e:
        return {"code": 500, "message": f"生成支付链接失败: {str(e)}", "data": {}}


# 支付宝异步回调可能以POST方式调用，这里同时兼容GET/POST
@orders_router.api_route("/callback", methods=["GET", "POST"])
async def alipay_callback(request: Request):
    """
    支付宝异步回调接口
    """
    try:
        # 接收参数：支付宝异步通知默认使用POST form-data
        if request.method == "POST":
            form_data = await request.form()
            data = {k: v for k, v in form_data.multi_items()}
        else:
            data = dict(request.query_params)

        if not data:
            return PlainTextResponse("failure")

        # 复制一份数据用于验签
        datames = {k: v for k, v in data.items()}
        
        # 删除字典中key为sign的记录
        sign = datames.pop('sign', None)
        if not sign:
            return PlainTextResponse("failure")
        
        # 鉴权 订单号 流水号
        pay = get_ali_object()
        flag = pay.verify(datames, sign)
        
        if flag:
            # 支付宝流水号
            transaction_no = datames.get('trade_no', '')
            # 订单号
            order_no = datames.get('out_trade_no', '')
            
            # 更新订单状态
            order = await _mark_order_paid(order_no, transaction_no)
            if not order:
                return PlainTextResponse("failure")

            # 根据订单类型执行不同的业务逻辑
            if order.product_type == "hotel":
                # 酒店订单处理逻辑
                pass
            elif order.product_type == "flight":
                # 机票订单处理逻辑
                pass
            elif order.product_type == "ticket":
                # 门票订单处理逻辑
                pass
            
            # 返回成功响应给支付宝
            return PlainTextResponse("success")
        else:
            print("鉴权失败")
            return PlainTextResponse("failure")
    except Exception as e:
        print(f"处理回调失败: {e}")
        return PlainTextResponse("failure")


@orders_router.get("/return")
async def alipay_return(request: Request):
    """
    支付宝同步回调接口（用户支付后跳转页面）
    """
    try:
        # 接收参数
        data = dict(request.query_params)
        # 复制一份数据用于验签
        datames = {k: v for k, v in data.items()}
        
        # 删除字典中key为sign的记录
        sign = datames.pop('sign', None)
        if not sign:
            return {"code": 400, "message": "缺少签名参数"}
        
        # 鉴权
        pay = get_ali_object()
        flag = pay.verify(datames, sign)
        
        if not flag:
            return {"code": 401, "message": "鉴权失败"}

        # 支付宝流水号
        transaction_no = datames.get('trade_no', '')
        # 订单号
        order_no = datames.get('out_trade_no', '')

        order = await _mark_order_paid(order_no, transaction_no)

        query = {
            "order_no": order_no
        }
        if transaction_no:
            query["transaction_no"] = transaction_no
        if order:
            query["status"] = str(order.status)
        redirect_url = f"http://localhost:5173/orders?{urlencode(query)}"
        return RedirectResponse(url=redirect_url)
    except Exception as e:
        print(f"处理同步回调失败: {e}")
        return {"code": 500, "message": f"处理同步回调失败: {str(e)}"}


@orders_router.get("/getall")
async def get_all_orders(user_id: str):
    """
    获取用户所有订单
    """
    try:
        # 查询用户的所有订单，并按创建时间倒序排列 
                "product_type": order.product_type,
                "product_id": order.product_id,
                "check_in_date": order.check_in_date.isoformat() if order.check_in_date else None,
                "check_out_date": order.check_out_date.isoformat() if order.check_out_date else None,
                "amount": float(order.amount) if order.amount else 0.0,
                "status": int(order.status) if order.status is not None else 0,
                "pay_time": order.pay_time.isoformat() if order.pay_time else None,
                "finish_time": order.finish_time.isoformat() if order.finish_time else None,
                "refund_status": int(order.refund_status) if order.refund_status is not None else 0,
                "create_time": order.create_time.isoformat() if order.create_time else None,
                "update_time": order.update_time.isoformat() if order.update_time else None
            })
        
        return {
            "code": 200,
            "message": "ok",
            "data": orders_list
        }
    except Exception as e:
        return {
            "code": 500,
            "message": f"获取订单列表失败: {str(e)}",
            "data": []
        }


@orders_router.get("/delete")
async def delete_order(order_id: str):
    """
    删除订单
    """
    try:
        # 删除订单
        order = await UserOrder.get_or_none(id=order_id)
        if not order:
            return {"code": 404, "message": "订单不存在", "data": {}}
        
        # 已退款处理中订单暂不允许删除
        if order.refund_status == 1:
            return {"code": 400, "message": "退款处理中，暂时无法删除订单", "data": {}}
        
        # 删除订单
        await order.delete()
        
        return {"code": 200, "message": "订单删除成功", "data": {"order_id": order_id}}
    except Exception as e:
        return {"code": 500, "message": f"删除订单失败: {str(e)}", "data": {}}
